package com.photo.system.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.photo.system.annotation.AuthCheck;
import com.photo.system.common.BaseResponse;
import com.photo.system.common.DeleteRequest;
import com.photo.system.common.ErrorCode;
import com.photo.system.common.ResultUtils;
import com.photo.system.constant.UserConstant;
import com.photo.system.exception.BusinessException;
import com.photo.system.exception.ThrowUtils;
import com.photo.system.model.dto.things.ThingUpdateMyRequest;
import com.photo.system.model.dto.things.ThingsQueryRequest;
import com.photo.system.model.entity.Things;
import com.photo.system.model.entity.User;
import com.photo.system.model.vo.LoginUserVO;
import com.photo.system.model.vo.ThingsVO;
import com.photo.system.service.ThingsService;
import com.photo.system.service.UserService;
import io.minio.GetPresignedObjectUrlArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.errors.MinioException;
import io.minio.http.Method;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

@RequestMapping("/minio")
@RestController
@Api(tags = {"摄影作品接口"})
public class ThingsController {

    @Autowired
    MinioClient minioClient;

    @Resource
    private UserService userService;

    @Resource
    private ThingsService thingsService;

    @PostMapping("/upload")
    @ApiOperation(value = "上传摄影作品")
    public String upload(@RequestParam("data") MultipartFile data, HttpServletRequest request) throws Exception {
        // 生成唯一文件名
        String originalFileName = data.getOriginalFilename();
        String fileExtension = originalFileName.substring(originalFileName.lastIndexOf("."));
        String uniqueFileName = generateUniqueFileName() + fileExtension;

        InputStream inputStream = data.getInputStream();
        minioClient.putObject(PutObjectArgs.builder().bucket("photo").object(uniqueFileName).stream(inputStream, data.getSize(), -1).contentType(data.getContentType()).build());

        // 构建完整的 URL
        String baseUrl = "http://39.98.107.158:9000/photo/";
        String fullUrl = baseUrl + uniqueFileName;

        return fullUrl; // 返回完整的 URL
    }

    /**
     * 生成唯一文件名
     *
     * @return 唯一文件名
     */
    private String generateUniqueFileName() {
        return System.currentTimeMillis() + "_" + java.util.UUID.randomUUID().toString().replace("-", "");
    }


    @PostMapping("/download")
    @ApiOperation(value = "下载摄影作品")
    public String download(@RequestParam("fileName") String fileName) throws Exception {
        try {
            // 获取预签名的URL，有效期为7天
            String url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket("photo").object(fileName).expiry(60 * 60 * 24 * 7) // 7天
                    .build());
            return url;
        } catch (MinioException | NoSuchAlgorithmException | InvalidKeyException e) {
            throw new RuntimeException("获取预签名URL失败", e);
        }
    }

    /**
     * 删除摄影作品（仅管理员）
     *
     * @param deleteRequest
     * @param request
     * @return
     */
    @PostMapping("/delete/all")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @ApiOperation(value = "删除摄影作品（仅管理员）")
    public BaseResponse<Boolean> deleteCategories(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
        }
        boolean result = thingsService.removeById(deleteRequest.getId());
        return ResultUtils.success(result);
    }

    /**
     * 删除摄影作品（仅用户）
     *
     * @param deleteRequest
     * @param request
     * @return
     */
    @PostMapping("/delete/my")
    @ApiOperation(value = "删除摄影作品（仅用户）")
    public BaseResponse<Boolean> deleteCategoriesBmy(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
        }
        Long userId = userService.getLoginUser(request).getId();
        Long id = deleteRequest.getId();
        QueryWrapper<Things> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id);
        Things things = thingsService.getOne(queryWrapper);
        if (things == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "作品不存在");
        }
        if (!things.getUserId().equals(userId.intValue())) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "没有权限删除");
        }

        boolean result = thingsService.removeById(deleteRequest.getId());
        return ResultUtils.success(result);
    }

    /**
     * 获取当前登录用户
     *
     * @param request
     * @return
     */
    @GetMapping("/get/login")
    public BaseResponse<LoginUserVO> getLoginUser(HttpServletRequest request) {
        User user = userService.getLoginUser(request);
        return ResultUtils.success(userService.getLoginUserVO(user));
    }

    /**
     * 创建摄影作品
     *
     * @param request
     * @return
     */
    @PostMapping("/add")
    @ApiOperation(value = "创建摄影作品")
    public BaseResponse<Long> addThings(@RequestParam("title") String title, @RequestParam("description") String description, @RequestParam("image") MultipartFile image, @RequestParam("categoryId") Long categoryId, HttpServletRequest request) {
        if (image == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "图片不能为空");
        }
        Long userId = getLoginUser(request).getData().getId();
        Things things = new Things();
        things.setTitle(title);
        things.setDescription(description);
        things.setCategoryId(categoryId);
        things.setUserId(Math.toIntExact(userId));

        // 调用 upload 方法并获取图片名称
        try {
            String imageUrl = upload(image, request);
            things.setImage(imageUrl);
        } catch (Exception e) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "图片上传失败");
        }

        boolean result = thingsService.save(things);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(things.getId());
    }

    /**
     * 更新摄影作品
     *
     * @param request
     * @return
     * @RequestBody thingUpdateMyRequest
     */
    @PostMapping("/update")
    @ApiOperation(value = "更新摄影作品")
    public BaseResponse<Boolean> updateThings(@RequestBody ThingUpdateMyRequest thingUpdateMyRequest, HttpServletRequest request) {
        if (thingUpdateMyRequest == null || thingUpdateMyRequest.getId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
        }
        Long userId = getLoginUser(request).getData().getId();
        Long id = thingUpdateMyRequest.getId();
        Things things = new Things();
        QueryWrapper<Things> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id);
        things = thingsService.getOne(queryWrapper);
        if (things == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "作品不存在");
        }
        BeanUtils.copyProperties(thingUpdateMyRequest, things);
        boolean result = thingsService.updateById(things);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "更新失败");
        return ResultUtils.success(result);
    }

    /**
     * 查询全部摄影作品
     *
     * @param thingsQueryRequest
     * @return
     */
    @PostMapping("/get/all")
    @ApiOperation(value = "查询全部摄影作品(所有人)")
    public BaseResponse<Page<ThingsVO>> getAllThings(@RequestBody ThingsQueryRequest thingsQueryRequest) {

        long current = thingsQueryRequest.getCurrent() == 0 ? 1 : thingsQueryRequest.getCurrent();
        long size = thingsQueryRequest.getPageSize() == 0 ? 10 : thingsQueryRequest.getPageSize();

        Page<ThingsVO> pageParam = new Page<>(current, size);
        Page<ThingsVO> thingsVOPage = thingsService.getQueryByAll(pageParam, thingsQueryRequest);
        return ResultUtils.success(thingsVOPage);

    }

    /**
     * 查询我的摄影作品
     *
     * @param request
     * @return
     * @RequestBody thingsQueryRequest
     */
    @PostMapping("/get/my")
    @ApiOperation(value = "查询我的摄影作品")
    public BaseResponse<Page<ThingsVO>> getMyThings(@RequestBody ThingsQueryRequest thingsQueryRequest, HttpServletRequest request) {

        Long userId = getLoginUser(request).getData().getId();
        long current = thingsQueryRequest.getCurrent() == 0 ? 1 : thingsQueryRequest.getCurrent();
        long size = thingsQueryRequest.getPageSize() == 0 ? 10 : thingsQueryRequest.getPageSize();

        Page<ThingsVO> pageParam = new Page<>(current, size);
        Page<ThingsVO> thingsVOPage = thingsService.getQueryByMy(pageParam, thingsQueryRequest, userId);
        return ResultUtils.success(thingsVOPage);
    }

}


